package localizer.main;


import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Looper;
import android.telephony.SmsManager;
import android.util.Log;

public class UpdateLocalizationService extends IntentService{

	static String username;
	static Location currentBestLocation;
	static String id;
	Config config;
	private static MyLocationListener myListener =  new MyLocationListener();
	private static LocationManager locationManager;
	private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 0; // in Meters
	private static final long MINIMUM_TIME_BETWEEN_UPDATES = 100; // in Milliseconds
	private static final long TIME_BETWEEN_UPDATES = 1000 * 60 * 5;
	private static final long TIME_WAITING_UPDATES = 1000;
	private static final int SIGNIFICANT_TIME_TO_CHANGE = 1000 * 60;
	private static final String TAG = "QuickNotesMainActivity";
	static Thread th;
	static String atividade;
	static String phone;
	static Context ctz;
	
	public UpdateLocalizationService() {
		super("update localization");
		
	}

	@Override
	protected void onHandleIntent(Intent arg0) {
		ConnectivityManager cm = (ConnectivityManager)getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); 
		NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
		boolean isConnected  =  ((activeNetwork != null) && activeNetwork.isConnectedOrConnecting());
		if( ! isConnected){
			return;
		}
		
		atividade = arg0.getExtras().getString("to");
		phone = arg0.getExtras().getString("phone");
		config = Config.getInstance(getApplicationContext());
		username = config.getUsername(getApplicationContext());
		ctz = UpdateLocalizationService.this.getApplicationContext();
		id = config.getID(getApplicationContext());
		updatePos();
	}
	
	private void updatePos(){
		Log.d("updatepos", "comecou a funcao" + ServiceBroadcastReciever.REPEAT_TIME + " " + ServiceBroadcastReciever.REPEAT_TIME2);
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		//locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) && 
		if(locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER ) && ! myListener.using()){
			Log.d("updatepos", "entrou no if");
			th = new Thread(){
				public void run(){
					Looper.prepare();
					myListener.start();
					Looper.loop();
				}
			};
			th.start();
		}
		Log.d("updatepos", "acabou a funcao");
	}


	/** Determines whether one Location reading is better than the current Location fix
	 * @param location  The new Location that you want to evaluate
	 * @param currentBestLocation  The current Location fix, to which you want to compare the new one
	 */
	protected static boolean isBetterLocation(Location location, Location currentBestLocation) {
		if (currentBestLocation == null) {
			// A new location is always better than no location
			return true;
		}

		// Check whether the new location fix is newer or older
		long timeDelta = location.getTime() - currentBestLocation.getTime();
		boolean isSignificantlyNewer = timeDelta > SIGNIFICANT_TIME_TO_CHANGE;
		boolean isSignificantlyOlder = timeDelta < -SIGNIFICANT_TIME_TO_CHANGE;
		boolean isNewer = timeDelta > 0;

		// If it's been more than two minutes since the current location, use the new location
		// because the user has likely moved
		if (isSignificantlyNewer) {
			return true;
			// If the new location is more than two minutes older, it must be worse
		} else if (isSignificantlyOlder) {
			return false;
		}

		// Check whether the new location fix is more or less accurate
		int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
		boolean isLessAccurate = accuracyDelta > 0;
		boolean isMoreAccurate = accuracyDelta < 0;
		boolean isSignificantlyLessAccurate = accuracyDelta > 200;

		// Check if the old and new location are from the same provider
		boolean isFromSameProvider = isSameProvider(location.getProvider(),
				currentBestLocation.getProvider());

		// Determine location quality using a combination of timeliness and accuracy
		if (isMoreAccurate) {
			return true;
		} else if (isNewer && !isLessAccurate) {
			return true;
		} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
			return true;
		}
		return false;
	}

	/** Checks whether two providers are the same */
	private static boolean isSameProvider(String provider1, String provider2) {
		if (provider1 == null) {
			return provider2 == null;
		}
		return provider1.equals(provider2);
	}
	private static class MyLocationListener implements LocationListener {
		
		boolean used;
		
		public MyLocationListener(){
			used = false;
		}
		
		public void start(){
			used = true;
			locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MINIMUM_TIME_BETWEEN_UPDATES, MINIMUM_DISTANCE_CHANGE_FOR_UPDATES, myListener);
		}
		
		public void end(){
			locationManager.removeUpdates(myListener);
			used = false;
			UpdateLocalizationService.th.interrupt();
		}
		
		public boolean using(){
			return used;
		}

		public void onLocationChanged(Location location) {
			Log.d("a","nova");
			end();
			makeUseOfNewLocation(location);
		}

		@Override
		public void onProviderDisabled(String arg0) {
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}

	}

	private static void makeUseOfNewLocation(Location lastKnownLocation) {
		if(isBetterLocation(lastKnownLocation, currentBestLocation)){
			currentBestLocation = lastKnownLocation;
			Log.d("Best", currentBestLocation.getLatitude() + " "+currentBestLocation.getLongitude());
			updateNewBestLocation();
		}
	}


	private static void updateNewBestLocation() {
		try{
			String urlaux = LoginActivity.SITE + "/update/?identifier="+id+"&username="+username+"&lati=" + currentBestLocation.getLatitude() + "&longi=" + currentBestLocation.getLongitude();
			Log.d("Servidor",urlaux);
			try {
				if( atividade.equals("server")){
					new DefaultHttpClient().execute( new HttpGet(urlaux) );
				} else {
					Log.d("mensagem", "enviada");
					SmsManager sms = SmsManager.getDefault();
					String mtext = currentBestLocation.getLatitude() + " " + currentBestLocation.getLongitude();
					if(atividade.equals("app")){
						mtext += (" " + SmsReceiver.ID_LOC); 
					}
			        sms.sendTextMessage(phone, null, mtext, null, null);	
					sms = null;
				}

			} catch ( Exception e ){
			}
		} catch ( Exception e){
		}
	}

}
